package ee.ut.maxorato_macobo.oop.mud;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

import ee.ut.maxorato_macobo.oop.mud.game.DataParser;
import ee.ut.maxorato_macobo.oop.mud.game.GameCommandSystem;
import ee.ut.maxorato_macobo.oop.mud.game.GameSpellSystem;
import ee.ut.maxorato_macobo.oop.mud.game.NpcLoaderPool;
import ee.ut.maxorato_macobo.oop.mud.game.NpcPool;
import ee.ut.maxorato_macobo.oop.mud.game.PlayerPool;
import ee.ut.maxorato_macobo.oop.mud.items.ItemLoaderPool;
import ee.ut.maxorato_macobo.oop.mud.items.ItemProcessorPool;
import ee.ut.maxorato_macobo.oop.mud.network.NetEventQueue;
import ee.ut.maxorato_macobo.oop.mud.network.NetPipelineFactory;

public class GameMain {
	private static final ServerBootstrap nettyBootstrap = new ServerBootstrap();

	public static void main(String[] args) {
		ExecutorService mainExecutor = Executors.newCachedThreadPool();
		ExecutorService subExecutor = Executors.newCachedThreadPool();
		
		nettyBootstrap.setFactory(new NioServerSocketChannelFactory(mainExecutor, subExecutor));
		nettyBootstrap.setPipelineFactory(new NetPipelineFactory());
		nettyBootstrap.bind(new InetSocketAddress(4003));
		
		GameCommandSystem.loadCommands();
		GameSpellSystem.loadSpells();
		DataParser.parseDataFile("testareafile.txt");
		
		lastTickTime = System.nanoTime();
		
		while(true) {
			NetEventQueue.process();
		}
	}
	
	private static long lastTickTime;
	
	public static long getNanosToTick() {
		return (lastTickTime + 400000000L) - System.nanoTime();
	}
	
	static long tickCounter = 0L;
	static long tickNanoTime = 0L;
	
	public static void doTick() {
		tickCounter++;
		tickNanoTime = System.nanoTime();
		
		lastTickTime += 400000000L;
		
		PlayerPool.doCommandTick();
		NpcPool.processTick();
		
		NpcLoaderPool.processTick();
		ItemLoaderPool.processTick();
		
		if((tickCounter % 4L) == 0L) {
			PlayerPool.doFightTick();
			NpcPool.doFightTick();
		}
		
		ItemProcessorPool.processTick();
		
		PlayerPool.doOutputTick();
		PlayerPool.processDisconnection();
	}
	
	public static long getTickNanoTime() {
		return tickNanoTime;
	}
}
